
package com.dianban.plugin.weixinpay;

import com.dianban.utils.MD5Utils;
import com.dianban.weixin.util.WeiXinUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.io.BufferedInputStream;
import java.io.InputStream;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;

/**
 * Plugin - 沙粮姐微信在线支付
 * @version 3.0
 */
@Component
public class SljWeiXinPayAppletPlugin {

    private Logger logger = LoggerFactory.getLogger(SljWeiXinPayAppletPlugin.class);

	@Value("${wechat.shaliangjie.app_id}")
	private String appId;
	@Value("${weixin.appSecret}")
	private String appSecret;
	@Value("${weixin.mchId}")
	private String mchId;

	public static final String UNIFIED_ORDER_URL = "https://api.mch.weixin.qq.com/pay/unifiedorder";

	public static final String QUERY_ORDER_URL = "https://api.mch.weixin.qq.com/pay/orderquery";

	public String getSiteUrl() {
		//return "http://yun.dianbang-st.com:9006/api/nengliang/wechat/asyncNotify/";
		return "https://rongyaotupay.aokxm.com/api/nengliang/wechat/asyncNotify/";
	}

    public String getNotifyUrl(String sn) {
		if(sn.indexOf("SLJ") == 0){
			return "https://rongyaotupay.aokxm.com/api/shaliangjie/wechat/asyncNotify/" +sn;
		}
        return getSiteUrl()+sn;
    }


	public String getSign(Map<String, Object> params) throws Exception {
		// 签名步骤一：按字典序排序参数
		String str = WeiXinUtils.FormatBizQueryParaMap(params, false);
		// 签名步骤二：在string后加入KEY
		str += "&key=" + appSecret;
		// 签名步骤三：MD5加密 签名步骤四：所有字符转为大写
		str = MD5Utils.getMD5Str(str).toUpperCase();
		return str;
	}

	public Map<String, String> getPrepayId(String url, String xmlParam) {
		HttpClient httpClient = new DefaultHttpClient();
		try {
			HttpPost httpPost = new HttpPost(url);
			httpPost.setEntity(new StringEntity(xmlParam, "UTF-8"));
			HttpResponse response = httpClient.execute(httpPost);
			String jsonStr = EntityUtils.toString(response.getEntity(), "UTF-8");

			// System.out.println(jsonStr);
			Map map = WeiXinUtils.doXMLParse(jsonStr);
			String return_code = (String) map.get("return_code");
			if (return_code.equals("SUCCESS")) {
				Map<String, String> result = new HashMap<String, String>();
				result.put("prepay_id", String.valueOf(map.get("prepay_id")));
				result.put("code_url", String.valueOf(map.get("code_url")));
				return result;
			} else {
				return null;
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			httpClient.getConnectionManager().shutdown();
		}
		return null;
	}

	public Map<String, Object> getParameterMap(String sn, String body,String detail,BigDecimal amount,String openid,HttpServletRequest request) {
		HashMap<String, Object> packageParams = new HashMap<String, Object>();
		String createNoncestr = WeiXinUtils.CreateNoncestr();
		packageParams.put("appid",appId);
		packageParams.put("mch_id", mchId);
		packageParams.put("nonce_str", createNoncestr);
		packageParams.put("body", StringUtils.abbreviate(body.replaceAll("[^0-9a-zA-Z\\u4e00-\\u9fa5 ]", ""), 30));
		packageParams.put("detail", StringUtils.abbreviate(detail.replaceAll("[^0-9a-zA-Z\\u4e00-\\u9fa5 ]", ""), 300));
		packageParams.put("out_trade_no", sn);
		// 这里写的金额为1 分到时修改
		packageParams.put("total_fee", amount.multiply(new BigDecimal(100)).setScale(0, BigDecimal.ROUND_HALF_UP).toString());
		packageParams.put("spbill_create_ip", request.getRemoteAddr().toString());
		packageParams.put("notify_url", getNotifyUrl(sn));
		packageParams.put("trade_type", "JSAPI");
		packageParams.put("openid", openid);
		try {
			String sign = getSign(packageParams);
			packageParams.put("sign", sign);
		} catch (Exception e) {
			e.printStackTrace();
		}
		Map<String, String> result = null;
		String xml = WeiXinUtils.getRequestXml(packageParams);
		logger.info("WeiXinUtils.getRequestXml:{}", xml);
		try {
			result = getPrepayId(UNIFIED_ORDER_URL, xml);
			if (result == null) {
				logger.error("统一支付接口获取预支付订单出错");
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		HashMap<String, Object> finalpackage = new HashMap<String, Object>();
		String timestamp = WeiXinUtils.getTimeStamp();
		if (result != null) {
			String prepay_id2 = "prepay_id=" + result.get("prepay_id");
			String packages = prepay_id2;
			finalpackage.put("appId", appId);
			finalpackage.put("timeStamp", timestamp);
			finalpackage.put("nonceStr", createNoncestr);
			finalpackage.put("package", packages);
			finalpackage.put("signType", "MD5");
		}
		try {
			String finalsign = getSign(finalpackage);
			finalpackage.put("paySign", finalsign);
			if (result != null && result.get("code_url") != null) {
				finalpackage.put("code_url", result.get("code_url"));
			}
		} catch (Exception e) {
			logger.error("统一支付接口获取预支付签名错误");
			e.printStackTrace();
		}
		return finalpackage;
	}

	public String  verifyNotify(String sn, BigDecimal amount,HttpServletRequest request) {
		String tradeSn = "";
		try {
			Map<String, Object> map = new HashMap();

			StringBuffer info = new StringBuffer();
			InputStream in = request.getInputStream();
			BufferedInputStream buf = new BufferedInputStream(in);
			byte[] buffer = new byte[1024];
			int iRead;
			while ((iRead = buf.read(buffer)) != -1) {
				info.append(new String(buffer, 0, iRead, "UTF-8"));
			}
			map = WeiXinUtils.doXMLParse(info.toString());
			if(map == null || map.isEmpty()){
				return tradeSn;
			}
			if ("SUCCESS".equals(map.get("return_code").toString()) && "SUCCESS".equals(map.get("result_code").toString())) {
				String sign = getSign(map);
				if (sign.equals(map.get("sign"))
						&& sn.equals(map.get("out_trade_no"))
						&& appId.equals(map.get("appid"))
						&& amount.multiply(new BigDecimal(100)).compareTo(new BigDecimal((String) map.get("total_fee"))) == 0) {
					tradeSn = String.valueOf(map.get("transaction_id"));
					return tradeSn;
				}
			}
			return tradeSn;
		} catch (Exception e) {
			e.printStackTrace();
			return tradeSn;
		}
	}

	public String getNotifyMessage() {
		return "<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>";
	}

	public String queryOrderStatus(String sn) {
		String tradeNo = "";
		HttpClient httpClient = new DefaultHttpClient();
		try {

			HashMap<String, Object> packageParams = new HashMap<String, Object>();
			String createNoncestr = WeiXinUtils.CreateNoncestr();

			packageParams.put("appid", appId);
			packageParams.put("mch_id", mchId);
			packageParams.put("nonce_str", createNoncestr);
			packageParams.put("out_trade_no", sn);
			String sign = getSign(packageParams);
			packageParams.put("sign", sign);
			String xml = WeiXinUtils.toXml(packageParams);
			HttpPost httpPost = new HttpPost(QUERY_ORDER_URL);
			httpPost.setEntity(new StringEntity(xml, "UTF-8"));
			HttpResponse response = httpClient.execute(httpPost);
			String jsonStr = EntityUtils.toString(response.getEntity(), "UTF-8");
			Map<String, Object> map = WeiXinUtils.doXMLParse(jsonStr);
			if ("SUCCESS".equals(map.get("return_code").toString()) && "SUCCESS".equals(map.get("result_code").toString()) && "SUCCESS".equals(map.get("trade_state").toString())) {
				String signResult = getSign(map);
				if (signResult.equals(map.get("sign"))
						&& sn.equals(map.get("out_trade_no"))
						&& map.get("appid").equals(appId)) {
					try {
						tradeNo = String.valueOf(map.get("transaction_id"));
						return tradeNo;
					} catch (Exception e) {
						e.printStackTrace();
						return tradeNo;
					}
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
			return tradeNo;
		} finally {
			httpClient.getConnectionManager().shutdown();
		}
		return tradeNo;
	}

}
